package com.hezhiqin.formework.webmvc.servlet;

import com.hezhiqin.formework.annotation.HZQRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: homeWork
 * @description:
 * @author: hezhiqin
 * @create: 2019-10-31 16:25
 */
public class HZQHandlerAdapter {


     public boolean supports(Object handler){
        return (handler instanceof HZQHandlerMapping);
     }


    public HZQModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        HZQHandlerMapping handlerMapping = (HZQHandlerMapping) handler;
        Map<String,Integer> paramIndexMapping = new HashMap<String,Integer>();

        Method method  = handlerMapping.getMethod();
        //提取方法中加了注解的参数
        Annotation[] [] pa = method.getParameterAnnotations();

        for (int i = 0; i < pa.length; i++) {

            for (Annotation a : pa[i]) {
                if(a instanceof HZQRequestParam){
                    String paramName = ((HZQRequestParam) a).value();
                    if(!"".equals(paramName.trim())){
                        paramIndexMapping.put(paramName, i);
                    }
                }

            }
        }

        //提取方法中的 request 和 response 参数
        Class<?> [] paramsTypes = method.getParameterTypes();
        for (int i = 0; i < paramsTypes.length ; i ++) {
            Class<?> type = paramsTypes[i];
            if(type == HttpServletRequest.class ||
                    type == HttpServletResponse.class){
                paramIndexMapping.put(type.getName(),i);
            }

        }


        //获得方法的形参列表
        Map<String,String[]> params = request.getParameterMap();

        //实参列表
        Object [] paramValues = new Object[paramsTypes.length];



        for (Map.Entry<String, String[]> parm : params.entrySet()) {

            String value = Arrays.toString(parm.getValue()).replaceAll("\\[|\\]","")
                    .replaceAll("\\s",",");
            if(!paramIndexMapping.containsKey(parm.getKey())){continue;}
            int index = paramIndexMapping.get(parm.getKey());
            paramValues[index] = caseStringValue(value,paramsTypes[index]);



        }

        if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())) {
            int reqIndex = paramIndexMapping.get(HttpServletRequest.class.getName());
            paramValues[reqIndex] = request;
        }



        if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())) {
            int respIndex = paramIndexMapping.get(HttpServletResponse.class.getName());
            paramValues[respIndex] = response;
        }

        Object returnValue = method.invoke(handlerMapping.getController(),paramValues);

        if(returnValue == null || returnValue instanceof Void){ return null; }

        if (method.getReturnType()==HZQModelAndView.class){
            return (HZQModelAndView) returnValue;
        }

        return  null;
    }

    private Object caseStringValue(String value, Class<?> paramsType) {
        if (String.class  == paramsType){
            return value;
        }

        if(Integer.class == paramsType){
            return Integer.valueOf(value);
        }else if(Double.class == paramsType){
            return Double.valueOf(value);
        }else {
            if (value!=null){
                return value.toString();
            }
            return null;
        }

    }


}
